#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
ExtractToMarkdown 构建和发布脚本
作者: Solming

使用方法:
python scripts/build.py --clean    # 清理构建文件
python scripts/build.py --build    # 构建包
python scripts/build.py --test     # 测试安装
python scripts/build.py --upload   # 上传到PyPI (需要配置)
"""

import os
import sys
import shutil
import subprocess
import argparse
from pathlib import Path

# 项目根目录
PROJECT_ROOT = Path(__file__).parent.parent.absolute()
os.chdir(PROJECT_ROOT)


def run_command(cmd, check=True):
    """运行命令并返回结果"""
    print(f"执行命令: {cmd}")
    try:
        result = subprocess.run(cmd, shell=True, check=check, 
                              capture_output=True, text=True)
        if result.stdout:
            print(result.stdout)
        return result
    except subprocess.CalledProcessError as e:
        print(f"命令执行失败: {e}")
        if e.stderr:
            print(f"错误信息: {e.stderr}")
        if check:
            sys.exit(1)
        return None


def clean_build():
    """清理构建文件"""
    print("🧹 清理构建文件...")
    
    # 清理目录列表
    clean_dirs = [
        'build',
        'dist', 
        '*.egg-info',
        '__pycache__',
        '.pytest_cache',
        '.coverage'
    ]
    
    # 递归清理__pycache__
    for root, dirs, files in os.walk('.'):
        for dir_name in dirs[:]:  # 使用切片复制避免修改正在迭代的列表
            if dir_name == '__pycache__':
                cache_path = os.path.join(root, dir_name)
                print(f"删除: {cache_path}")
                shutil.rmtree(cache_path, ignore_errors=True)
                dirs.remove(dir_name)
    
    # 清理构建文件
    for pattern in clean_dirs:
        if '*' in pattern:
            run_command(f"rm -rf {pattern}", check=False)
        else:
            if os.path.exists(pattern):
                print(f"删除: {pattern}")
                shutil.rmtree(pattern, ignore_errors=True)
    
    print("✅ 清理完成")


def check_dependencies():
    """检查构建依赖"""
    print("🔍 检查构建依赖...")
    
    required_packages = ['setuptools', 'wheel', 'twine']
    missing = []
    
    for package in required_packages:
        result = run_command(f"pip show {package}", check=False)
        if result is None or result.returncode != 0:
            missing.append(package)
    
    if missing:
        print(f"❌ 缺少依赖: {', '.join(missing)}")
        print("安装缺少的依赖...")
        run_command(f"pip install {' '.join(missing)}")
    
    print("✅ 依赖检查完成")


def build_package():
    """构建包"""
    print("📦 构建包...")
    
    # 检查依赖
    check_dependencies()
    
    # 构建源码分发包和wheel包
    run_command("python setup.py sdist bdist_wheel")
    
    # 显示构建结果
    if os.path.exists('dist'):
        print("\n📁 构建文件:")
        for file in os.listdir('dist'):
            file_path = os.path.join('dist', file)
            size = os.path.getsize(file_path)
            print(f"  {file} ({size:,} bytes)")
    
    print("✅ 构建完成")


def test_installation():
    """测试安装"""
    print("🧪 测试安装...")
    
    # 创建临时虚拟环境进行测试
    test_env = "test_env"
    
    try:
        print("创建测试虚拟环境...")
        run_command(f"python -m venv {test_env}")
        
        # 激活虚拟环境并安装
        if sys.platform == "win32":
            pip_cmd = f"{test_env}\\Scripts\\pip"
            python_cmd = f"{test_env}\\Scripts\\python"
        else:
            pip_cmd = f"{test_env}/bin/pip"
            python_cmd = f"{test_env}/bin/python"
        
        print("在测试环境中安装包...")
        run_command(f"{pip_cmd} install --upgrade pip")
        run_command(f"{pip_cmd} install dist/*.whl")
        
        print("测试导入...")
        test_script = """
import sys
try:
    import converter_engine
    print(f"✅ 成功导入 converter_engine")
    print(f"版本: {converter_engine.__version__}")
    print(f"作者: {converter_engine.__author__}")
    sys.exit(0)
except ImportError as e:
    print(f"❌ 导入失败: {e}")
    sys.exit(1)
"""
        with open("test_import.py", "w", encoding='utf-8') as f:
            f.write(test_script)
        
        run_command(f"{python_cmd} test_import.py")
        
    finally:
        # 清理
        if os.path.exists(test_env):
            shutil.rmtree(test_env, ignore_errors=True)
        if os.path.exists("test_import.py"):
            os.remove("test_import.py")
    
    print("✅ 测试完成")


def upload_package():
    """上传包到PyPI"""
    print("🚀 上传包到PyPI...")
    
    # 检查twine
    result = run_command("pip show twine", check=False)
    if result is None or result.returncode != 0:
        print("安装twine...")
        run_command("pip install twine")
    
    # 检查包
    print("检查包...")
    run_command("twine check dist/*")
    
    # 上传到TestPyPI（可选）
    print("\n是否要先上传到TestPyPI进行测试？(y/n): ", end="")
    if input().lower() == 'y':
        print("上传到TestPyPI...")
        run_command("twine upload --repository testpypi dist/*")
    
    # 上传到PyPI
    print("\n⚠️  即将上传到正式PyPI!")
    print("确认继续？(y/n): ", end="")
    if input().lower() == 'y':
        print("上传到PyPI...")
        run_command("twine upload dist/*")
        print("✅ 上传完成")
    else:
        print("❌ 取消上传")


def main():
    parser = argparse.ArgumentParser(description='ExtractToMarkdown 构建脚本')
    parser.add_argument('--clean', action='store_true', help='清理构建文件')
    parser.add_argument('--build', action='store_true', help='构建包')
    parser.add_argument('--test', action='store_true', help='测试安装')
    parser.add_argument('--upload', action='store_true', help='上传到PyPI')
    parser.add_argument('--all', action='store_true', help='执行完整流程')
    
    args = parser.parse_args()
    
    if not any([args.clean, args.build, args.test, args.upload, args.all]):
        parser.print_help()
        return
    
    print(f"🚀 ExtractToMarkdown 构建脚本")
    print(f"项目目录: {PROJECT_ROOT}")
    print("=" * 50)
    
    if args.all or args.clean:
        clean_build()
    
    if args.all or args.build:
        build_package()
    
    if args.all or args.test:
        test_installation()
    
    if args.upload:  # 不包含在all中，需要手动指定
        upload_package()
    
    print("\n🎉 操作完成!")


if __name__ == "__main__":
    main() 